//
//  CMAS3ObjectController.m
//  Perilla
//
//  Created by Martin Schiøth Dyrby on 10/14/12.
//  Copyright (c) 2012 Martin Schiøth Dyrby. All rights reserved.
//

#import "CMAS3ObjectController.h"
#import "CMAS3Object.h"
#import "CMMidiObject.h"

@interface CMAS3ObjectController (PrivateAPI)

- (void) addNewObject: (NSNotification *) note;

@end

@implementation CMAS3ObjectController

@synthesize objects;
@synthesize midiObjects;
@synthesize logView;

- (id)init
{
	if((self = [super init]))
	{
        [[NSNotificationCenter defaultCenter]
         addObserver:self
         selector: @selector(socketMessageReceived:)
         name:@"socketMessageReceived"
         object: nil];
        
        [[NSNotificationCenter defaultCenter]
         addObserver:self
         selector: @selector(midiMessageReceived:)
         name:@"midiMessageReceived"
         object: nil];
        
        NSMutableDictionary* objs = [[NSMutableDictionary alloc] init];
        midiObjects = objs;
    }
    return self;
}

-(NSString*) getMidiNoteFromNumber: (int) intNum {

    int div = 12;
    
    int octave = intNum/div;
    int tone = intNum - octave*12;
    octave = octave - 2;
    switch (tone) {
        case 0:
            return [NSString stringWithFormat: @"C%d", octave];
        case 1:
            return [NSString stringWithFormat: @"C#%d", octave];
        case 2:
            return [NSString stringWithFormat: @"D%d", octave];
        case 3:
            return [NSString stringWithFormat: @"D#%d", octave];
        case 4:
            return [NSString stringWithFormat: @"E%d", octave];
        case 5:
            return [NSString stringWithFormat: @"F%d", octave];
        case 6:
            return [NSString stringWithFormat: @"F#%d", octave];
        case 7:
            return [NSString stringWithFormat: @"G%d", octave];
        case 8:
            return [NSString stringWithFormat: @"G#%d", octave];
        case 9:
            return [NSString stringWithFormat: @"A%d", octave];
        case 10:
            return [NSString stringWithFormat: @"A#%d", octave];
        case 11:
            return [NSString stringWithFormat: @"B%d", octave];
        default:
            return [NSString stringWithFormat: @"%d", intNum];

    }
    
    
}

-(void) socketMessageReceived: (NSNotification *) note {
    NSDictionary* dict = (NSDictionary*)note.object;
    NSData* data = [dict valueForKey:@"data"];
    
    NSString *strData = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
    NSArray *listItems = [strData componentsSeparatedByString:@";"];
    NSString* type = [listItems objectAtIndex:0];
    NSString* name = [listItems objectAtIndex:1];
    if([type isEqualToString:@"midi"]) {
        NSString* midi = [listItems objectAtIndex:2];
        float minimum = [[listItems objectAtIndex:3] floatValue];
        float maximum = [[listItems objectAtIndex:4] floatValue];
        
        CMMidiObject* midiObject = [CMMidiObject alloc];
        midiObject.uname = name;
        midiObject.midi = midi;
        midiObject.minimum = minimum;
        midiObject.maximum = maximum;
        
        [midiObjects setObject:midiObject forKey:midi];
    }
}

-(void) midiMessageReceived: (NSNotification *) note {
    NSDictionary* dict = (NSDictionary*)note.object;
    
    int type = [[dict valueForKey:@"type"] intValue];
    int message = (type/16)*16;
    int num = [[dict valueForKey:@"num"] intValue];
    int value = [[dict valueForKey:@"value"] intValue];
    float floatvalue = (float)value;
    
    NSString* strType;
    if(message  == 144) {
        strType = [NSString stringWithFormat: @"NOTE ON (%@)", [self getMidiNoteFromNumber: num]];
    } else if(message == 128) {
        strType = [NSString stringWithFormat: @"NOTE OFF (%@)", [self getMidiNoteFromNumber: num]];
    } else if(message == 176) {
        strType = [NSString stringWithFormat: @"CONTROL (%d)", num];
    } else if(message == 192) {
        strType = [NSString stringWithFormat: @"PROGRAM CHANGE (%d)", num];
    } else {
        strType = [NSString stringWithFormat: @"[UNKNOWN TYPE] (%d)", num];
    }
    
    NSString* midiKey = [[NSString stringWithFormat:@"%d", message] stringByAppendingString:[NSString stringWithFormat:@"-%d", num]];
    NSLog(@"midiKey: %@", midiKey);
    CMMidiObject* midiObject = [midiObjects objectForKey:midiKey];

    if(midiObject.uname != nil) {
        float calculatedValue = (midiObject.maximum - midiObject.minimum) * (floatvalue/127.0) + midiObject.minimum;
        NSDictionary* dict = [[NSDictionary alloc] initWithObjectsAndKeys: midiObject.uname, @"name", [NSString stringWithFormat:@"%f",calculatedValue], @"value", nil];
        [[NSNotificationCenter defaultCenter] postNotificationName:@"midiMessageMatch" object:dict];
    }
    

    NSString* log = [[NSString stringWithFormat:@"\nmidi %@ (%@) value %d", midiKey, strType, value] stringByAppendingString: [logView string]];
    [logView setString: log];
}

- (IBAction)clearConnection:(id)sender {
    [midiObjects removeAllObjects];
}
- (IBAction)clearLog:(id)sender {
    [logView setString: @""];
}
@end
